package ee.edisoft.quartz;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import ee.edisoft.common.db.DataBase;
import ee.edisoft.common.model.DetailModel;
import ee.edisoft.common.model.HeaderModel;
 
public class SchedulerJob extends QuartzJobBean
{
	 
	protected void executeInternal(JobExecutionContext context)
			throws JobExecutionException {
		Properties prop = new Properties();
		InputStream ins = this.getClass().getClassLoader().getResourceAsStream("sync.properties");
		try {
			prop.load(ins);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		String xmlFolder = prop.getProperty("xml");
		String archiveFolder = prop.getProperty("archive");
		String style = prop.getProperty("xsl");

				File directory = new File(xmlFolder);
				File archive = new File(archiveFolder);
				 
				if(directory.isDirectory()){
					if(directory.list().length>0){
					for( File f : directory.listFiles() )
					{
						try {
							try {
								getXml(f.getName(), style, xmlFolder);
							} catch (DOMException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							} catch (TransformerException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							boolean success = f.renameTo(new File(archive, f.getName()));
							if (!success)
								System.out.println("file move failed");
						} catch (XPathExpressionException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (ParserConfigurationException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (SAXException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			 
			}else{
		 
//				System.out.println("This is not a directory");
		 
			}
	    }		
		 
			  private static void getXml(String file, String style, String xmlFolder) 
					   throws ParserConfigurationException, SAXException, 
					          IOException, XPathExpressionException, TransformerException, DOMException, ParseException {
					SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

					TransformerFactory tFactory = TransformerFactory.newInstance();
					Transformer transformer = tFactory.newTransformer(new StreamSource(style));
					ByteArrayOutputStream outputStream = new ByteArrayOutputStream();;
						transformer.transform(new StreamSource(xmlFolder + "/" + file), new StreamResult(outputStream));

						DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
					          domFactory.setNamespaceAware(true); 
					    DocumentBuilder builder = domFactory.newDocumentBuilder();
					    Document doc = builder.parse(new ByteArrayInputStream(outputStream.toByteArray()));
					    XPath xpath = XPathFactory.newInstance().newXPath();
						    	HeaderModel header = new HeaderModel();
							    Node headerNumber = (Node) xpath.compile("//DocumentSettings/DocumentNumber/text()").evaluate(doc, XPathConstants.NODE);
							    Node documenttype = (Node) xpath.compile("//DocumentSettings/DocumentType/text()").evaluate(doc, XPathConstants.NODE);
							    Node receiversystemtype = (Node) xpath.compile("//DocumentSettings/ReceiverSystemType/text()").evaluate(doc, XPathConstants.NODE);
							    Node documentdate1 = (Node) xpath.compile("//DocumentSettings/DocumentDate1/text()").evaluate(doc, XPathConstants.NODE);
							    Node documentdate2 = (Node) xpath.compile("//DocumentSettings/DocumentDate2/text()").evaluate(doc, XPathConstants.NODE);
							    Node senderiln = (Node) xpath.compile("//DocumentSettings/Sender/ILN/text()").evaluate(doc, XPathConstants.NODE);
							    Node sendercodebyreceiver = (Node) xpath.compile("//DocumentSettings/Sender/CodeByReceiver/text()").evaluate(doc, XPathConstants.NODE);
							    Node sendername = (Node) xpath.compile("//DocumentSettings/Sender/Name/text()").evaluate(doc, XPathConstants.NODE);
							    Node senderaddress = (Node) xpath.compile("//DocumentSettings/Sender/Address/text()").evaluate(doc, XPathConstants.NODE);
							    Node receiveriln = (Node) xpath.compile("//DocumentSettings/Receiver/ILN/text()").evaluate(doc, XPathConstants.NODE);
							    Node receivercodebyreceiver = (Node) xpath.compile("//DocumentSettings/Receiver/CodeByReceiver/text()").evaluate(doc, XPathConstants.NODE);
							    Node receivername = (Node) xpath.compile("//DocumentSettings/Receiver/Name/text()").evaluate(doc, XPathConstants.NODE);
							    Node receiveraddress = (Node) xpath.compile("//DocumentSettings/Receiver/Address/text()").evaluate(doc, XPathConstants.NODE);
						    	
							    header.set("documentnumber", Integer.valueOf(headerNumber.getNodeValue()));
							    header.set("receiversystemtype", receiversystemtype.getNodeValue());
							    header.set("documenttype", documenttype.getNodeValue());
							    header.set("documentdate1", (Date)formatter.parse(documentdate1.getNodeValue()));
							    header.set("documentdate2", (Date)formatter.parse(documentdate2.getNodeValue()));
							    header.set("senderiln", Long.valueOf(senderiln.getNodeValue()));
							    header.set("sendercodebyreceiver", Integer.valueOf(sendercodebyreceiver.getNodeValue()));
							    header.set("sendername", sendername.getNodeValue());
							    header.set("senderaddress", senderaddress.getNodeValue());
							    header.set("receiveriln", Long.valueOf(receiveriln.getNodeValue()));
							    header.set("receivercodebyreceiver", Integer.valueOf(receivercodebyreceiver.getNodeValue()));
							    header.set("receivername", receivername.getNodeValue());
							    header.set("receiveraddress", receiveraddress.getNodeValue());

							  Node nodeNumber = (Node) xpath.compile("//Line-Item/LineNumber/text()").evaluate(doc, XPathConstants.NODE);
						    Node nodeCode = (Node) xpath.compile("//Line-Item/SupplierItemCode/text()").evaluate(doc, XPathConstants.NODE);
						    Node nodeDesc = (Node) xpath.compile("//Line-Item/ItemDescription/text()").evaluate(doc, XPathConstants.NODE);
						    Node nodeQty = (Node) xpath.compile("//Line-Item/InvoiceQuantity/text()").evaluate(doc, XPathConstants.NODE);
						    Node nodePrice = (Node) xpath.compile("//Line-Item/InvoiceUnitNetPrice/text()").evaluate(doc, XPathConstants.NODE);
					    	DetailModel detail = new DetailModel();
					    	detail.set("linenumber", Integer.valueOf(nodeNumber.getNodeValue()));
					    	detail.set("supplieritemcode", Integer.valueOf(nodeCode.getNodeValue()));
					    	detail.set("itemdescription", nodeDesc.getNodeValue());
					    	detail.set("invoicequantity", Double.parseDouble(nodeQty.getNodeValue()));
					    	detail.set("invoiceunitnetprice", Double.parseDouble(nodePrice.getNodeValue()));
					    	detail.save();
					    	header.add(detail);
					    	header.save();
							System.out.println("before save");
							try {
								DataBase.close();
								System.out.println("after save");
							} catch (Exception e) {
								System.out.println("error saving " + e.getMessage());
							}
				  }

	}
